
#include "ParamLine.h"
//

template<int dimention>
int CParamLine<dimention>::Compute_Parm_Line(float t, CParmPoint* pt)
{
	for (int i=0; i<dimention; i++)
		pt->Set(i, m_p0[X] + m_v[X] * t);

	return 0;
}

template<>
int CParamLine<2>::Compute_Parm_Line(float t, CParmPoint* pt)
{
	// this function computes the value of the sent parametric 
	// line at the value of t

	pt->SetX(m_p0[X] + m_v[X] * t);
	pt->SetY(m_p0[Y] + m_v[Y] * t);

	return 0;

} // end Compute_Parm_Line

template<>
int CParamLine<3>::Compute_Parm_Line(float t, CParmPoint* pt)
{
	// this function computes the value of the sent parametric 
	// line at the value of t

	pt->SetX(m_p0[X] + m_v[X] * t);
	pt->SetY(m_p0[Y] + m_v[Y] * t);
	pt->SetZ(m_p0[Z] + m_v[Z] * t);

	return 0;

} // end Compute_Parm_Line

template<int dimention>
int CParamLine<dimention>::Intersect(CParamLine& rhs, float *t1, float *t2)
{
	return 0;
}

template<>
int CParamLine<2>::Intersect(CParamLine& rhs, float *t1, float *t2)
{
	// this function computes the interesection of the two parametric 
	// line segments the function returns true if the segments 
	// interesect and sets the values of t1 and t2 to the t values that 
	// the intersection occurs on the lines p1 and p2 respectively, 
	// however, the function may send back t value not in the range [0,1]
	// this means that the segments don't intersect, but the lines that 
	// they represent do, thus a retun of 0 means no intersection, a 
	// 1 means intersection on the segments and a 2 means the lines 
	// intersect, but not necessarily the segments and 3 means that 
	// the lines are the same, thus they intersect everywhere

	// basically we have a system of 2d linear equations, we need
	// to solve for t1, t2 when x,y are both equal (if that's possible)

	// step 1: test for parallel lines, if the direction vectors are 
	// scalar multiples then the lines are parallel and can't possible
	// intersect unless the lines overlap

	float det_p1p2 = (m_v[X] * rhs.m_v[Y] - m_v[Y] * rhs.m_v[X]);

	if (fabs(det_p1p2) <= EPSILON_E5)
	{
		// at this point, the lines either don't intersect at all
		// or they are the same lines, in which case they may intersect
		// at one or many points along the segments, at this point we 
		// will assume that the lines don't intersect at all, but later
		// we may need to rewrite this function and take into 
		// consideration the overlap and singular point exceptions
		return(PARM_LINE_NO_INTERSECT);

	} // end if

	// step 2: now compute the t1, t2 values for intersection
	// we have two lines of the form
	// p    = p0    +  v*t, specifically
	// p1   = p10   + v1*t1

	// p1.x = p10.x + v1.x*t1
	// p1.y = p10.y + v1.y*t1

	// p2 = p20 + v2*t2
	// p2   = p20   + v2*t2

	// p2.x = p20.x + v2.x*t2
	// p2.y = p20.y + v2.y*t2
	// solve the system when x1 = x2 and y1 = y2
	// explained in chapter 4


	*t1 = (rhs.m_v[X] * (m_p0[Y] - rhs.m_p0[Y]) - rhs.m_v[Y] * (m_p0[X] - rhs.m_p0[X]) )
		/det_p1p2;

	*t2 = (m_v[X] * (m_p0[Y] - rhs.m_p0[Y]) - m_v[Y] * (m_p0[X] - rhs.m_p0[X])  )
		/det_p1p2;


	// test if the lines intersect on the segments
	if ((*t1>=0) && (*t1<=1) && (*t2>=0) && (*t2<=1))
		return(PARM_LINE_INTERSECT_IN_SEGMENT);
	else
		return(PARM_LINE_INTERSECT_OUT_SEGMENT);
}